<script setup lang="ts">
import TableAction from '#/components/TableAction/index.vue'
import type { ApiPagination, ApiPaginationParams } from '#types/utils'
import { uniqueByField } from '@vben/utils'
import { Button, message } from 'ant-design-vue'
import { computed, ref, watch } from 'vue'

import type { VbenFormProps } from '@vben/common-ui'
import { useVbenModal } from '@vben/common-ui'
import type { VxeGridProps } from '@vben/plugins/vxe-table'
// 全局组件不允许使用 '#/adapter/vxe-table' 下的 useVbenVxeGrid 否则表单会报组件未注册
import { $t } from '@vben/locales'
import { useVbenVxeGrid } from '@vben/plugins/vxe-table'

import SelectModal from './SelectModal.vue'

interface Props {
    /**
     * 已经选中的实体
     */
    options?: Array<Record<string, any>>

    /**
     * 主键
     */
    rowKey?: string
    /**
     * 主键
     */
    labelKey?: string
    columns?: VxeGridProps['columns']
    width?: number | string
    // 是否多选
    multiple?: boolean
    modelValue: Array<number | string> | null | (number | string) | undefined
    formOptions?: Partial<VbenFormProps>
    gridOptions?: Partial<VxeGridProps>
    api?: (params: ApiPaginationParams<Record<string, any>>) => Promise<ApiPagination<any>>
    maxShowLength?: number
    disabled?: boolean
    height?: number
    placeholder?: string
    showKey?: string
    confirmText?: string
}

const props = withDefaults(defineProps<Props>(), {
    options: () => [],
    rowKey: 'id',
    columns: () => [
        {
            title: $t('common.name'),
            field: 'name'
        }
    ],
    width: 1000,

    multiple: true,
    labelKey: 'name',
    formOptions: () => {
        return {}
    },
    gridOptions: () => {
        return {}
    },
    api: undefined,
    maxShowLength: 1,
    disabled: false,
    height: 400,
    placeholder: '',
    showKey: '',
    confirmText: $t('common.choose')
})

const emit = defineEmits<{
    (
        event: 'update:modelValue',
        value: Array<number | string> | null | (number | string) | undefined
    ): void
    (event: 'updateLabel', label: number | string): void
}>()

const formOptions: VbenFormProps = {
    // 默认展开
    collapsed: false,
    // 控制表单是否显示折叠按钮
    showCollapseButton: true,
    collapsedRows: 1,
    // 按下回车时是否提交表单
    submitOnEnter: true,
    resetButtonOptions: {
        show: false
    },
    ...props.formOptions
}

const proxyConfig: VxeGridProps['proxyConfig'] = props.gridOptions?.proxyConfig || {}

const gridOptions: VxeGridProps<any> = {
    height: props.height,

    pagerConfig: {
        enabled: false
    },
    ...props.gridOptions,
    columns: [
        {
            align: 'center',
            title: props.multiple ? '' : '',
            type: 'checkbox',
            width: 50
        },
        ...props.columns
    ],
    proxyConfig
}

const localOptions = ref<Array<Record<string, any>>>([])

const optionsFix = computed(() => {
    const { options, rowKey } = props

    return uniqueByField([...options, ...localOptions.value], rowKey)
})

// 全部选中的内容
const curSelectedOptions = computed(() => {
    return optionsFix.value.filter((item) => {
        const arr = props.modelValue

        const val = item[props.rowKey]
        return Array.isArray(arr) ? arr.includes(val) : val === arr
    })
})

const [Modal, modalApi] = useVbenModal({
    connectedComponent: SelectModal,

    class: `w-[${props.width}px]`,
    confirmText: $t(props.confirmText)
})

const [Grid, GridApi] = useVbenVxeGrid({
    formOptions,
    gridOptions: {
        ...gridOptions,
        columns: [
            ...(gridOptions.columns || []),
            {
                field: 'action',
                fixed: 'right',
                slots: { default: 'action' },
                title: $t('common.action'),
                width: 120
            }
        ],
        data: curSelectedOptions.value
    },
    gridEvents: {
        // checkboxChange,
        // radioChange,
        // checkboxAll
    },
    showSearchForm: false
})

watch(
    curSelectedOptions,
    () => {
        GridApi?.setGridOptions({
            data: curSelectedOptions.value
        })
    },
    { immediate: true }
)

// 显示状态才能活动table的api
watch(
    () => props.modelValue,
    () => {
        // initCheckBox()
    },
    { immediate: true }
)

/**
 * table 操作
 * @param record
 */
function getActions(record: any) {
    const arr: any[] = [
        {
            icon: 'ant-design:delete-outlined',
            color: '#bb1b1b',
            tooltip: $t('common.delete'),
            onClick() {
                handleDel(record)
            }
        }
    ]
    return arr
}

function openModal() {
    modalApi.setData({ value: props.modelValue })
    modalApi.open()
}

function onConfirm(val: any, records: any[]) {
    localOptions.value = records
    emit('update:modelValue', val)
}

function handleDel(record: any) {
    const { multiple, modelValue, rowKey } = props

    if (multiple) {
        if (Array.isArray(modelValue)) {
            const index = modelValue.indexOf(record[rowKey])
            if (index !== -1) {
                modelValue.splice(index, 1)
                emit('update:modelValue', modelValue)
            }
        }
    } else {
        emit('update:modelValue', null)
    }
}

function getSelectRows(isFull = true) {
    const grid = GridApi?.grid
    if (grid && Object.keys(grid).length > 0) {
        return gridOptions?.checkboxConfig?.reserve
            ? [...grid.getCheckboxRecords(isFull), ...grid.getCheckboxReserveRecords(isFull)]
            : grid.getCheckboxRecords(isFull)
    }

    return []
}

function handleDelBatch() {
    const rows = getSelectRows()

    const ids = rows.map((item: any) => item[props.rowKey])

    if (ids.length === 0) {
        message.error($t('common.comfirmDeleteData'))
    }

    rows.forEach((item: any) => {
        handleDel(item)
    })
}
</script>
<template>
    <div>
        <div class="flex gap-3">
            <Button @click="openModal" type="primary">
                {{ $t('common.choose') }}
            </Button>
            <Button @click="handleDelBatch"> {{ $t('common.delete') }} </Button>
        </div>
        <Grid>
            <template #action="{ row }">
                <TableAction :actions="getActions(row)" />
            </template>
        </Grid>
        <Modal v-bind="props" @confirm="onConfirm" />
    </div>
</template>

<style lang="less" scoped>
.table-select-box {
    position: relative;
    display: inline-flex;
    width: 100%;
    min-width: 0;
    padding: 4px 11px;
    color: rgba(9, 9, 11, 0.88);
    font-size: 14px;
    line-height: 1.5714285714285714;
    background-color: hsl(0 0% 100%);
    background-image: none;
    border-width: 1px;
    border-style: solid;
    border-color: hsl(240 5.9% 90%);
    border-radius: 8px;
    transition: all 0.2s;
    cursor: pointer;

    &.ant-input-disabled {
        background-color: rgba(9, 9, 11, 0.04);
        cursor: default;
    }
}
</style>
